home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 33
/
Amiga Format AFCD33 (Issue 117, Dec 1998).iso
/
-seriously_amiga-
/
graphics
/
splitmpegppc
/
src
/
parsers.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-07
|
7KB
|
273 lines
/*
* Copyright (c) 1994 Michael Simmons.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL MICHAEL SIMMONS BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF MICHAEL SIMMONS
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE MICHAEL SIMMONS SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND MICHAEL SIMMONS HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* I can be contacted via
* Email: michael@ecel.uwa.edu.au
* Post: P.O. Box 506, NEDLANDS WA 6009, AUSTRALIA
*
* Amigaversion by Tobias Seiler in 1997
* Email: tabs@blader.com
*/
/*
* Routines to parse the different parts of a pack
*/
#include "main.h"
#define check_marker \
{ \
get_bits1(&data); \
if ( data != 1) \
return (err | ERR_INVALID_MARKER); \
}
/*
* Parses the pack header
*
*/
int parse_pack_header(Pack_Header *pack_header)
{
unsigned int data;
int err = ERR_PARSE_PACK_HDR;
flush_bits(32); /* Flush PACK_START_CODE */
get_bits4(&data);
if( data != 2)
return (err | ERR_INVALID_BITS);
/* Get System Clock Reference*/
get_bits1(&data);
pack_header->SCR_hibit = data;
get_bits2(&data);
pack_header->SCR = data << 30;
check_marker;
get_bits15(&data);
pack_header->SCR |= data << 15;
check_marker;
get_bits15(&data);
pack_header->SCR |= data;
check_marker;
check_marker;
/* Get Mux Rate */
get_bits22(&data);
pack_header->mux_rate = data;
check_marker;
return NO_ERROR;
}
/*
* Parses the system header
*/
int parse_system_header( System_Header *system_header)
{
unsigned int data;
unsigned int stream_id;
int err = ERR_PARSE_SYSTEM_HDR;
flush_bits(32); /* flush SYSTEM_HEADER_START_CODE */
/* extract system header information */
get_bits16(&data);
system_header->header_length = data;
check_marker;
get_bits22(&data);
system_header->rate_bound = data;
check_marker;
get_bits6(&data);
system_header->audio_bound = data;
get_bits1(&data);
system_header->fixed_flag = data;
get_bits1(&data);
system_header->CSPS_flag = data;
get_bits1(&data);
system_header->audio_lock_flag = data;
get_bits1(&data);
system_header->video_lock_flag = data;
check_marker;
get_bits5(&data);
system_header->video_bound = data;
get_bits8(&data);
system_header->reserved_byte = data;
/* flag STD buffer bounds for each stream as invalid*/
for( stream_id=0; stream_id< MAX_NUM_STREAMS; stream_id++)
system_header->STD_flag[stream_id] = FALSE;
while ( next_bits(1,1)){
/* get stream number */
get_bits8(&data);
if( data < (RESERVED_STREAM & 0xff) || data > (RESERVED_DATA_STREAM_15 & 0xff))
return (err | ERR_INVALID_STREAM_NUM );
stream_id = data - (RESERVED_STREAM & 0xff);
get_bits2(&data);
if( data != 3 )
return (err | ERR_INVALID_BITS);
/* Extract the STD buffer bounds for stream stream_id and flag it as valid */
get_bits1(&data);
system_header->STD_scale_bound[stream_id] = data;
get_bits13(&data);
system_header->STD_size_bound[stream_id] = data;
system_header->STD_flag[stream_id] = TRUE;
}
return NO_ERROR;
}
/*
* Reads in a packet from the stream
* Updates the current stream info
* Create a buffer and put the packet data in it
*/
int parse_packet(Packet *packet)
{
unsigned int data = NULL;
unsigned int byte_count;
int err = ERR_PARSE_SYSTEM_HDR;
int i,stream_num;
char *bptr;
get_bits24(&data);
get_bits8(&data);
if( data < (RESERVED_STREAM & 0xff) || data > (RESERVED_DATA_STREAM_15 & 0xff))
return (err | ERR_INVALID_STREAM_NUM );
packet->stream_id = data;
stream_num = packet->stream_id - (RESERVED_STREAM & 0xff);
get_bits16(&data);
packet->packet_length = data;
byte_count =0;
packet->STD_flag=packet->PTS_Flag=packet->DTS_Flag = FALSE;
if( packet->stream_id != PRIVATE_STREAM_2 ){
/* flush stuffing bytes */
while( next_bits(8,0xff)){
flush_bits(8);
byte_count++;
}
if( next_bits(2,1)){
flush_bits(2);
/* Get STD buffer size and flag it as present in packet*/
get_bits1(&data);
streamInfo[stream_num].STD_scale=data;
get_bits13(&data);
streamInfo[stream_num].STD_size=data;
packet->STD_flag=TRUE;
byte_count +=2;
}
if( next_bits(4,2)){
flush_bits(4);
/* Get presentation time stamp and flag it as present in packet*/
get_bits1(&data);
streamInfo[stream_num].PTS_hibit = data;
get_bits2(&data);
streamInfo[stream_num].PTS = data << 30;
check_marker;
get_bits15(&data);
streamInfo[stream_num].PTS |= data << 15;
check_marker;
get_bits15(&data);
streamInfo[stream_num].PTS |= data;
check_marker;
packet->PTS_Flag=TRUE;
byte_count +=5;
}else if (next_bits(4,3)){
flush_bits(4);
/* Get presentation time stamp and decoding time stamp */
/* and flag them as present in packet*/
get_bits1(&data);
streamInfo[stream_num].PTS_hibit = data;
get_bits2(&data);
streamInfo[stream_num].PTS = data << 30;
check_marker;
get_bits15(&data);
streamInfo[stream_num].PTS |= data << 15;
check_marker;
get_bits15(&data);
streamInfo[stream_num].PTS |= data;
check_marker;
packet->PTS_Flag=TRUE;
if( !next_bits(4,1) )
return (err | ERR_INVALID_BITS);
flush_bits(4);
get_bits1(&data);
streamInfo[stream_num].DTS_hibit = data;
get_bits2(&data);
streamInfo[stream_num].DTS = data << 30;
check_marker;
get_bits15(&data);
streamInfo[stream_num].DTS |= data << 15;
check_marker;
get_bits15(&data);
streamInfo[stream_num].DTS |= data;
check_marker;
packet->DTS_Flag=TRUE;
byte_count +=10;
}else{
if( !next_bits(8,0x0f))
return (err | ERR_INVALID_BITS);
flush_bits(8);
byte_count++;
}
}
/* create a buffer to contain the packet data and copy it in */
packet->buffer_size = packet->packet_length - byte_count;
packet->buffer = (char *) malloc(packet->buffer_size);
if(packet->buffer == NULL){
return (err | ERR_MALLOC);
}
bptr = packet->buffer;
for( i=0; i < (packet->buffer_size); i++){
get_bits8(&data);
*bptr++=(char) data;
}
return NO_ERROR;
}